﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace NetTopologySuite.Utilities
{
	public class CollectionUtil
	{
		public static IList Transform(ICollection coll, CollectionUtil.FunctionDelegate<object> func)
		{
			IList list = new ArrayList();
			foreach (object obj in coll)
			{
				list.Add(func(obj));
			}
			return list;
		}

		public static IList<T> Cast<T>(ICollection coll)
		{
			IList<T> list = new List<T>(coll.Count);
			foreach (object obj in coll)
			{
				list.Add((T)((object)obj));
			}
			return list;
		}

		public static IList<TOut> Cast<TIn, TOut>(ICollection<TIn> coll) where TIn : class where TOut : class
		{
			IList<TOut> list = new List<TOut>(coll.Count);
			foreach (TIn tin in coll)
			{
				list.Add(tin as TOut);
			}
			return list;
		}

		public static IList<T> Transform<T>(IList<T> list, CollectionUtil.FunctionDelegate<T> function)
		{
			IList<T> list2 = new List<T>(list.Count);
			foreach (T obj in list)
			{
				list2.Add(function(obj));
			}
			return list2;
		}

		public static IList<TResult> Transform<T, TResult>(IList<T> list, CollectionUtil.FunctionDelegate<T, TResult> function)
		{
			IList<TResult> list2 = new List<TResult>(list.Count);
			foreach (T obj in list)
			{
				list2.Add(function(obj));
			}
			return list2;
		}

		public static void Apply(ICollection coll, CollectionUtil.FunctionDelegate<object> func)
		{
			foreach (object obj in coll)
			{
				func(obj);
			}
		}

		public static void Apply<T>(IEnumerable<T> coll, CollectionUtil.FunctionDelegate<T> func)
		{
			foreach (T obj in coll)
			{
				func(obj);
			}
		}

		public static IList Select(ICollection coll, CollectionUtil.FunctionDelegate<object, bool> func)
		{
			IList list = new ArrayList();
			foreach (object obj in coll)
			{
				if (func(obj))
				{
					list.Add(obj);
				}
			}
			return list;
		}

		public static IList<T> Select<T>(IEnumerable<T> items, CollectionUtil.FunctionDelegate<T, bool> func)
		{
			IList<T> list = new List<T>();
			foreach (T t in items)
			{
				if (func(t))
				{
					list.Add(t);
				}
			}
			return list;
		}

		public static TOut[] Cast<TIn, TOut>(TIn[] array)
		{
			TOut[] array2 = new TOut[array.Length];
			Array.Copy(array, array2, array.Length);
			return array2;
		}

		internal static IEnumerable<T> StableSort<T>(IEnumerable<T> items)
		{
			return CollectionUtil.StableSort<T>(items, Comparer<T>.Default);
		}

		internal static IEnumerable<T> StableSort<T>(IEnumerable<T> items, IComparer<T> comparer)
		{
			return items.OrderBy((T x) => x, comparer);
		}

		public delegate T FunctionDelegate<T>(T obj);

		public delegate TResult FunctionDelegate<T, TResult>(T obj);
	}
}
